// Base64Coder.h	class Base64Coder

#ifndef _KC_BASE_64_CODER__H_2008_KC_
#define _KC_BASE_64_CODER__H_2008_KC_

#include <iostream>
#include <string>
 
namespace kc_sf
{

class Base64Coder
{
    public:

        // stałe
        static const unsigned int Base64MaxLineLength = 76;

        Base64Coder( unsigned int encoded_line_length = 
                        Base64MaxLineLength,
                     bool add_crlf_at_end = true ); ///@todo req_rfc_conformancy

        bool 
        encode( const std::string &input, std::string &output ) const;

        bool 
        encode( const char *input, unsigned int input_size, 
                std::string &output ) const;
        
        bool decode( const std::string &input, std::string &output ) const;

        bool 
        decode( const std::string &input, 
                char *output, unsigned int &output_size ) const;
        
        std::string name() const    {
            return "base64";
        }
        
    private:

        // składowe
        unsigned int    bc_line_length;     // ilość znaków w kodowanej linii
        bool            bc_add_crlf_at_end; // flaga czy dodawać na końcu znaki CRLF
        
        // stałe
        static const int Base64CharNr = 64;
        static const unsigned char Base64Alphabet[ Base64CharNr + 1 ];
        static const std::string CRLF;
        enum IndexIgnoredValues 
            { new_line = -3, equal = -2, error = -1 };

        // kopiowanie niemożliwe - same nagłówki
        Base64Coder( const Base64Coder & );
        Base64Coder & operator=( const Base64Coder & );        
                
        // pomocnicze funkcje    
        int index( unsigned char c ) const;                     // mapowanie literki z tablicy alfabetu na jej indeks 
        
        unsigned int 
        omitCRLF( const std::string &input, unsigned int &pos ) const; // omijanie znakow nowej linii w napisie
};

}

#endif // _KC_BASE_64_CODER__H_2008_KC_

/* test encode:
 
    Base64Coder coder;
    std::cout << "dl:" << length << std::endl; 
    std::string out;
    coder.encode( buffer, length, out );
    std::cout << out << std::endl; 

 */
